package normal.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import normal.component.MJComboBox;
import normal.ui.detail.DetailPanel;

import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import util.StringProcesser;


public class UIBuilder {
	
	@SuppressWarnings("unchecked")
	public static void process(Element element, JComponent parent, JComponent rootComponent) {
		if (element.isRootElement() || element.getNodeType() == Node.ELEMENT_NODE) {
			JComponent pComponent = createComponent(element, rootComponent);
			if (parent == null) {
				rootComponent.add(pComponent);
			}else if (pComponent != null) {
				if (parent instanceof JScrollPane) {
					((JScrollPane) parent).setViewportView(pComponent);
				} else if (parent instanceof JSplitPane) {
					if (pComponent.getName().equals("left")) {
						((JSplitPane)parent).setLeftComponent(pComponent);
					} else if (pComponent.getName().equals("right")) {
						((JSplitPane)parent).setRightComponent(pComponent);
					}
				} else {
					parent.add(pComponent);
				}
			}
			Iterator<Element> iterator = element.elementIterator();
			int hGap = Integer.parseInt(element.attributeValue("hGap", "0"));
			int vGap = Integer.parseInt(element.attributeValue("vGap", "0"));
			while (iterator.hasNext()) {
				Element child = iterator.next();
				process(child, pComponent, rootComponent);
				if (iterator.hasNext()) {
					if (hGap > 0) {
						pComponent.add(Box.createHorizontalStrut(hGap));
					} else if (vGap > 0) {
						pComponent.add(Box.createVerticalStrut(vGap));
					}
				}
			}
		}
	}

	@SuppressWarnings("unchecked")
	private static JComponent createComponent(Element element, JComponent rootComponent) {
		JComponent component = null;
		String componentType = element.getName();
		if (componentType.equals("Box")) {
			if ("Horizontal".equals(element.attributeValue("orientation"))) {
				component = Box.createHorizontalBox();
			} else if ("Vertical".equals(element.attributeValue("orientation", "Horizontal"))) {
				component = Box.createVerticalBox();
			}
		} else if (componentType.equals("JPanel")) {
			JPanel panel = new JPanel();
			
			component = panel;
		} else if (componentType.equals("JLabel")) {
			JLabel label = new JLabel();
			Iterator<Element> iterator = element.elementIterator();
			while (iterator.hasNext()) {
				Element child = iterator.next();
				if (child.getNodeType() == Node.ELEMENT_NODE) {
					if (child.getName().equals("text")) {
						label.setText(child.getTextTrim());
					}
				}
			} 
			component = label;
		} else if (componentType.equals("JTextField")) {
			JTextField textField = new JTextField();
			textField.setColumns(Integer.parseInt(element.attributeValue("columns", "10")));
			textField.setEditable(Boolean.valueOf(element.attributeValue("editable", "true")));
			component = textField;
		} else if (componentType.equals("JComboBox")) {
			MJComboBox comboBox = new MJComboBox();
			Iterator<Element> iterator = element.elementIterator();
			while (iterator.hasNext()) {
				Element child = iterator.next();
				if (child.getNodeType() == Node.ELEMENT_NODE) {
					if (child.getName().equals("items")) {
						comboBox.setItems(child.getTextTrim().split(","));
					} else if (child.getName().equals("itemsValues")) {
						comboBox.setValues(StringProcesser.toIntArray(child.getTextTrim()));
					}
				}
			} 
			
			comboBox.setEditable(Boolean.valueOf(element.attributeValue("editable", "true")));
			component = comboBox;
		} else if (componentType.equals("JTextArea")) {
			JTextArea textArea = new JTextArea();
			textArea.setRows(Integer.parseInt(element.attributeValue("rows", "4")));
			textArea.setColumns(Integer.parseInt(element.attributeValue("columns", "10")));
			textArea.setLineWrap(true);
			textArea.setEditable(Boolean.valueOf(element.attributeValue("editable", "true")));
			component = textArea;
		} else if (componentType.equals("ScrollPane")) {
			JScrollPane scrollPane = new JScrollPane();
			if ("Horizontal".equals(element.attributeValue("orientation"))) {

			} else if ("Vertical".equals(element.attributeValue("orientation", "Horizontal"))) {
			}
			component = scrollPane;
		} else if (componentType.equals("JSplitPane")) {
			JSplitPane splitPane = new JSplitPane();
			if ("Horizontal".equals(element.attributeValue("orientation"))) {
				splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
			} else if ("Vertical".equals(element.attributeValue("orientation", "Horizontal"))) {
				splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
			}
			splitPane.setDividerLocation(Integer.parseInt(element.attributeValue("dividerLocation", "500")));
			splitPane.setDividerSize(Integer.parseInt(element.attributeValue("dividerSize", "3")));
			component = splitPane;
		}
		if (element.attributeValue("name") != null) {
			component.setName(element.attributeValue("name"));
			if (rootComponent instanceof DetailPanel) {
				((DetailPanel)rootComponent).addToMap(component.getName(), component);
			}
		}
		if (component != null) {
			
		}
		return component;
	}
	
	public static void processXmlx(String file, JComponent panel) {
		Element rootElement = new UIBuilder().loadXML(file).getRootElement();
		if (rootElement.hasContent() && rootElement.hasMixedContent()) {
			process(rootElement, null, panel);
		}
	}

	@SuppressWarnings("unchecked")
	public static Object processXml(String file, JComponent panel) {
		Element rootElement = new UIBuilder().loadXML(file).getRootElement();
		if (rootElement.hasContent() && rootElement.hasMixedContent()) {
			Iterator<Element> iterator = rootElement.elementIterator();
			while (iterator.hasNext()) {

				Element element = iterator.next();
				if (element.getNodeType() == Node.ELEMENT_NODE) {

//					T target = org.springframework.beans.BeanUtils.instantiate(clazz);
					Iterator<Element> childIterator = element.elementIterator();
					Map<String, String> valueMap = new HashMap<String, String>();
					while (childIterator.hasNext()) {
						Element childElement = childIterator.next();
						if (childElement.getNodeType() == Node.ELEMENT_NODE) {
							try {
								valueMap.put(childElement.getName(), childElement.getTextTrim());
//								BeanUtils.setProperty(target, childElement.getName(), childElement.getTextTrim());
//								if (childElement.getName().equals("label")) {
//									label = new JLabel();
//									label.setText(childElement.getTextTrim());
//								} else if (childElement.getName().equals("componentType")) {
//									component = createComponent(childElement.getTextTrim());
//								} else if (childElement.getName().equals("componentName")) {
//									if (component != null) {
//										component.setName(childElement.getTextTrim());
//									}
//								} else if (childElement.getName().equals("size")) {
//									setSize(childElement.getTextTrim());
//								} else if (childElement.getName().equals("value")) {
//									setValue(component, childElement.getTextTrim());
//								}
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
					createComponent(panel, valueMap);
				}
			}
		}
		return null;
	}
	
	private static void createComponent(JComponent panel, Map<String, String> valueMap) {
		String componentType = valueMap.get("componentType");
		if (componentType == null) {
			System.out.println("err no componentType");
			return;
		}
		JLabel label = new JLabel(valueMap.get("label"));
		JComponent component = null;
		if (componentType.equals("JTextField")) {
			JTextField textField = new JTextField();
			textField.setColumns(Integer.parseInt(valueMap.get("size")));
			textField.setEditable(false);
			component = textField;
		} else if (componentType.equals("JComboBox")) {
			MJComboBox comboBox = new MJComboBox(valueMap.get("items").split(","), StringProcesser.toIntArray(valueMap.get("itemsValues")));
			comboBox.setEditable(false);
			component = comboBox;
		} else if (componentType.equals("JTextArea")) {
			JTextArea textArea = new JTextArea();
			int[] size = StringProcesser.toIntArray(valueMap.get("size"));
			textArea.setRows(size[0]);
			textArea.setColumns(size[1]);
			textArea.setLineWrap(true);
			textArea.setEditable(false);
			component = textArea;
		}
		component.setName(valueMap.get("componentName"));
		component.setForeground(Color.GRAY);
		if (panel instanceof DetailPanel) {
			((DetailPanel)panel).addOne(label, component);
		}
	}

	public Document loadXML(String file) {
		SAXReader reader = new SAXReader();
		try {
			reader.setEncoding("utf8");
			return reader.read(getClass().getResource(file).getFile());
		} catch (Exception e) {
			e.printStackTrace();
			return DocumentFactory.getInstance().createDocument();
		}
	}
	
	public static void main(String[] args) {
		
	}
}
